package com.chezai.client.activitys;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.chezai.client.R;
import com.chezai.client.adapter.BluetoothListAdapter;
import com.chezai.client.global.TerminalApplication;
import com.chezai.client.utils.PreferenceManager;
import com.obd.commands.io.ObdGatewayService;
import com.orhanobut.logger.Logger;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * 蓝牙设置页面
 */
public class BluetoothListActivity extends BaseActivity implements BluetoothListAdapter.BindOnClickListener {

    public static final int CONNECT_FAIL = 1;
    public static final int CONNECT_SUCCESS = 2;
    private static String BLUETOOTH_LIST_PREFERENCE = "bluetooth_list_preference";
    private static String BLUETOOTH_NAME_PREFERENCE = "bluetooth_name_preference";
    @BindView(R.id.tv_title)
    TextView tvTitle;
    @BindView(R.id.bondedDevices)
    TextView bondedDevices;
    @BindView(R.id.tvConnetState)
    TextView tvConnetState;
    @BindView(R.id.lvHasBound)
    ListView lvHasBound;
    @BindView(R.id.tv_search_devices)
    TextView tvSearchDevices;
    @BindView(R.id.list_search_devices)
    ListView listSearchDevices;
    private Activity activity = BluetoothListActivity.this;
    private List<BluetoothDevice> searchDevicesList;
    private List<BluetoothDevice> boundDevicesList;
    private BluetoothListAdapter mSearchAdapter;
    private BluetoothListAdapter mBoundAdapter;
    private BluetoothAdapter mAdapter;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case CONNECT_FAIL:
                    BluetoothDevice bld = (BluetoothDevice) msg.obj;
                    tvConnetState.setText("连接 " + bld.getName() + "失败");
                    TerminalApplication.getTerminalContext().startLiveData();
                    PreferenceManager.putString(BLUETOOTH_LIST_PREFERENCE, bld.getAddress());
                    PreferenceManager.putString(BLUETOOTH_NAME_PREFERENCE, bld.getName());
                    bondedDevices.setText(bld.getName() + "  " + bld.getAddress());
                    break;
                case CONNECT_SUCCESS:
                    BluetoothDevice bl = (BluetoothDevice) msg.obj;
                    TerminalApplication.getTerminalContext().startLiveData();
                    PreferenceManager.putString(BLUETOOTH_LIST_PREFERENCE, bl.getAddress());
                    PreferenceManager.putString(BLUETOOTH_NAME_PREFERENCE, bl.getName());
                    bondedDevices.setText(bl.getName() + "  " + bl.getAddress());
                    tvConnetState.setText("连接 " + bl.getName() + "成功");
                    break;
                default:
                    break;
            }
        }
    };
    private BroadcastReceiver receiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    if (searchDevicesList.indexOf(device) == -1)
                        searchDevicesList.add(device);
                    mSearchAdapter.notifyDataSetChanged();
                    setPullLvHeight(listSearchDevices);
                }

            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                setProgressBarIndeterminateVisibility(false);
                setTitle("");
            } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String name = device.getName();
                if (device.getName().equalsIgnoreCase(name)) {
                    int connectState = device.getBondState();
                    switch (connectState) {
                        case BluetoothDevice.BOND_NONE:  //10
                            break;
                        case BluetoothDevice.BOND_BONDING:  //11
                            break;
                        case BluetoothDevice.BOND_BONDED:   //12
                            getBltList();
                            try {
                                connect(device, handler);
                            } catch (Exception e) {
                                Logger.t("connect").i("onReceive: " + e.getMessage());
                            }
                            break;
                    }
                }
            }
        }
    };

    @Override
    public int getLayoutId() {
        return R.layout.bluetooth_main;
    }

    @Override
    public void initView(Bundle savedInstanceState) {

    }

    @Override
    public void initData() {
        tvTitle.setText("配置车载odb");
        searchDevicesList = new ArrayList<>();
        boundDevicesList = new ArrayList<>();

        mBoundAdapter = new BluetoothListAdapter(this, boundDevicesList, this);
        lvHasBound.setAdapter(mBoundAdapter);


        mSearchAdapter = new BluetoothListAdapter(this, searchDevicesList, this);
        listSearchDevices.setAdapter(mSearchAdapter);

        listSearchDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                mAdapter.cancelDiscovery();
                Toast.makeText(getApplicationContext(), "正在配对蓝牙设备", Toast.LENGTH_SHORT).show();
                BluetoothDevice device = searchDevicesList.get(position);
                createBond(device);
            }
        });
        checkBluetooth();
        getBltList();

        IntentFilter mFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        mFilter.addAction(BluetoothDevice.ACTION_FOUND);
        mFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        mFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
        mFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        mFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        registerReceiver(receiver, mFilter);

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
        registerReceiver(receiver, filter);

        String address = PreferenceManager.getString(BLUETOOTH_LIST_PREFERENCE, "");
        String name = PreferenceManager.getString(BLUETOOTH_NAME_PREFERENCE, "");
        bondedDevices.setText(name + "  " + address);
    }

    private void createBond(BluetoothDevice device) {
        try {
            Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
            createBondMethod.invoke(device);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 与设备解除配对
    public boolean removeBond(Class btClass, BluetoothDevice btDevice) throws Exception {
        Method removeBondMethod = btClass.getMethod("removeBond");
        Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
        return returnValue.booleanValue();
    }

    private void startSearchBluetooth() {
        setProgressBarIndeterminateVisibility(true);
        setTitle("开始搜索....");
        searchDevicesList.clear();
        mSearchAdapter.notifyDataSetChanged();
        if (!mAdapter.isDiscovering()) {
            mAdapter.cancelDiscovery();
        }
        mAdapter.startDiscovery();
    }

    /**
     * 检测 蓝牙是否可用
     */
    private void checkBluetooth() {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mAdapter == null) {
            Toast.makeText(this, "查找不到蓝牙设备", Toast.LENGTH_SHORT).show();
        } else {
            if (!mAdapter.isEnabled()) {
                Intent intent = new Intent();
                intent.setAction(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                intent.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
                startActivity(intent);
            }
        }
    }

    private void connect(final BluetoothDevice bluetoothDevice, final Handler handler) {
        TerminalApplication.getTerminalContext().stopLiveData();
        TerminalApplication.getTerminalContext().closeBluetoothSocket();
        //链接的操作应该在子线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TerminalApplication._sock = bluetoothDevice.createRfcommSocketToServiceRecord(ObdGatewayService.MY_UUID);
                    TerminalApplication._sock.connect();

                    Message msg = new Message();
                    msg.obj = bluetoothDevice;
                    msg.what = CONNECT_SUCCESS;
                    handler.sendMessage(msg);
                    Logger.t("BluetoothSocket").i("connect: ----" + TerminalApplication._sock.isConnected());
                } catch (IOException e) {
                    Message msg = new Message();
                    msg.obj = bluetoothDevice;
                    msg.what = CONNECT_FAIL;
                    handler.sendMessage(msg);
                    e.printStackTrace();
                } catch (Exception e) {

                }

            }
        }).start();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

    /**
     * 获得系统保存的配对成功过的设备，并尝试连接
     */
    private void getBltList() {
        boundDevicesList.clear();
        if (mAdapter == null) return;
        //获得已配对的远程蓝牙设备的集合
        Set<BluetoothDevice> devices = mAdapter.getBondedDevices();
        for (BluetoothDevice device : devices) {
            boundDevicesList.add(device);
        }
        mBoundAdapter.notifyDataSetChanged();
        setPullLvHeight(lvHasBound);

    }


    @Override
    public void choseData(BluetoothDevice device, int clikeType) {

        if (clikeType == BluetoothListAdapter.BIND) {
            if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                mAdapter.cancelDiscovery();
                Toast.makeText(activity, "开始配对蓝牙设备", Toast.LENGTH_SHORT).show();
                createBond(device);
            } else {
                mAdapter.cancelDiscovery();
                PreferenceManager.putString(BLUETOOTH_LIST_PREFERENCE, device.getAddress());
                PreferenceManager.putString(BLUETOOTH_NAME_PREFERENCE, device.getName());
                bondedDevices.setText(device.getName() + "  " + device.getAddress());
                connect(device, handler);
            }
        } else {
            try {
                removeBond(device.getClass(), device);
                boundDevicesList.remove(device);
                mBoundAdapter.notifyDataSetChanged();
                setPullLvHeight(lvHasBound);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    }

    private void setPullLvHeight(ListView pull) {
        int totalHeight = 0;
        ListAdapter adapter = pull.getAdapter();
        for (int i = 0, len = adapter.getCount(); i < len; i++) { //listAdapter.getCount()返回数据项的数目
            View listItem = adapter.getView(i, null, pull);
            listItem.measure(0, 0); //计算子项View 的宽高
            totalHeight += listItem.getMeasuredHeight(); //统计所有子项的总高度
        }

        ViewGroup.LayoutParams params = pull.getLayoutParams();
        params.height = totalHeight + (pull.getDividerHeight() * (pull.getCount() - 1));
        pull.setLayoutParams(params);
    }

    @OnClick({R.id.btn_back, R.id.btSeachDevices, R.id.btStopSeach})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_back:
                finish();
                break;
            case R.id.btSeachDevices:
                startSearchBluetooth();
                break;
            case R.id.btStopSeach:
                if (mAdapter.isDiscovering()) {
                    mAdapter.cancelDiscovery();
                }
                break;
        }
    }
}

